package form
{
   import flash.events.*;
   import flash.display.*;
   import flash.text.*;
   import flash.geom.*;
   import flash.utils.*;
   import flash.net.*;
   import flash.ui.*;
   // fl component
   import fl.controls.*;
   import fl.events.*;
   // as3core
   import com.adobe.images.*;
   // greensock
   import com.greensock.*;
   import com.greensock.easing.*;

   /**
    * @author   cjboy1984
    */
   public class PhotoEditorPanel extends MovieClip
   {
      // fla
      public var mcPhoto:MovieClip;
      public var slZoomer:Slider;

      // photo container
      private var container:Sprite;
      private var CONTAINER_W:Number;
      private var CONTAINER_H:Number;

      /* constructor */
      public function PhotoEditorPanel()
      {
         stop();

         tabEnabled = false;
         tabChildren = false;
         focusRect = false;

         addEventListener(Event.ADDED_TO_STAGE, onAdd);
         addEventListener(Event.REMOVED_FROM_STAGE, onRemove);
      }

      // ------------------ LINE -------------------

      // ################ Protected ################

      // ################# Private #################

      private function onAdd(e:Event):void
      {
         CONTAINER_W = mcPhoto.width;
         CONTAINER_H = mcPhoto.height;

         container = new Sprite();
         container.addChild(DEF.fileLoaderContent);

         // scale content & put it center
         var sr:Number = MyUtils.getScale(container, CONTAINER_W, CONTAINER_H, 'proportionalOutside');
         if (PhotoEditor.PHOTO_POS == null || PhotoEditor.PHOTO_SCALE == -1)
         {
            container.scaleX = container.scaleY = sr;
            container.x = (CONTAINER_W - container.width) / 2;
            container.y = (CONTAINER_H - container.height) / 2;

            slZoomer.value = slZoomer.minimum = sr;
         }
         else
         {
            container.scaleX = container.scaleY = PhotoEditor.PHOTO_SCALE;
            container.x = PhotoEditor.PHOTO_POS.x;
            container.y = PhotoEditor.PHOTO_POS.y;

            slZoomer.minimum = sr;
            slZoomer.value = PhotoEditor.PHOTO_SCALE;
         }

         // mouse
         mcPhoto.buttonMode = true;

         // add container
         mcPhoto.addChild(container);

         // drag & zoom
         mcPhoto.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
         mcPhoto.addEventListener(MouseEvent.MOUSE_WHEEL, onWheel);

         slZoomer.addEventListener(SliderEvent.CHANGE, onSliding);
      }

      private function onRemove(e:Event):void
      {
         slZoomer.removeEventListener(SliderEvent.CHANGE, onSliding);

         // drag & zoom
         mcPhoto.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
         mcPhoto.removeEventListener(MouseEvent.MOUSE_WHEEL, onWheel);
         stage.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag);
         stage.removeEventListener(MouseEvent.ROLL_OUT, onStopDrag);

         // ave flag
         PhotoEditor.PHOTO_POS = new Point(container.x, container.y);
         PhotoEditor.PHOTO_SCALE = container.scaleX;
         container = null;

         // save thumbnail
         var bmpData:BitmapData = new BitmapData(CONTAINER_W, CONTAINER_H, false);
         bmpData.draw(mcPhoto);
         DEF.usrPhoto = bmpData;
         DEF.usrPhotoByteArray = new JPGEncoder(50).encode(DEF.usrPhoto);
         //MyDebug.drawBitmapData(DEF.usrPhoto); // >test<
      }

      // ------------------ LINE -------------------

      private function onSliding(e:SliderEvent):void
      {
         if (container.numChildren < 1) return;

         // stop dragging
         container.stopDrag();

         var centerPos:Point = new Point(CONTAINER_W / 2, CONTAINER_H / 2);
         var globalPos:Point = mcPhoto.localToGlobal(centerPos);
         var imgLocalPos:Point = container.globalToLocal(globalPos);
         var a:Point = mcPhoto.globalToLocal(container.localToGlobal(imgLocalPos));

         // scale
         container.scaleX = container.scaleY = slZoomer.value;

         // pos
         var b:Point = mcPhoto.globalToLocal(container.localToGlobal(imgLocalPos));
         var newX:Number = container.x - (b.x - a.x);
         var newY:Number = container.y - (b.y - a.y);

         // limit x, y
         if (newX + container.width < CONTAINER_W)
         {
            newX = CONTAINER_W - container.width;
         }
         else if(newX > 0)
         {
            newX = 0;
         }
         if (newY + container.height < CONTAINER_H)
         {
            newY = CONTAINER_H - container.height;
         }
         else if (newY > 0)
         {
            newY = 0;
         }

         container.x = newX;
         container.y = newY;
      }

      // ------------------ LINE -------------------

      private function onWheel(e:MouseEvent):void
      {
         if (container.numChildren < 1) return;

         // avoid drag & zoom
         container.stopDrag();

         var orgW:Number = DEF.fileLoaderContent.width;
         var orgH:Number = DEF.fileLoaderContent.height;

         var scaleXY:Number = container.scaleX; // proportional x and y
         scaleXY += e.delta / Math.abs(e.delta) * 0.01 || 0; // edit scroll-speed here

         var newW:Number = orgW * scaleXY;
         var newH:Number = orgH * scaleXY;

         // limit width, height
         if (newW >= CONTAINER_W && newH >= CONTAINER_H && scaleXY <= slZoomer.maximum)
         {
            //trace('onWheel >> scaleXY / max =', scaleXY, '/', slZoomer.maximum);

            // control slider
            slZoomer.value = scaleXY;

            // scale proportionally
            container.scaleX = container.scaleY = scaleXY;

            // Try to have the map zoom to the position at which the mouse is located. (localX, localY: The x/y at which the event occurred relative to the containing sprite.)
            var newX:Number = mcPhoto.mouseX - e.localX * container.scaleX;
            var newY:Number = mcPhoto.mouseY - e.localY * container.scaleY;

            // limit x, y
            if (newX + newW < CONTAINER_W)
            {
               newX = CONTAINER_W - newW;
            }
            else if(newX > 0)
            {
               newX = 0;
            }
            if (newY + newH < CONTAINER_H)
            {
               newY = CONTAINER_H - newH;
            }
            else if (newY > 0)
            {
               newY = 0;
            }

            container.x = newX;
            container.y = newY;
         }
      }

      // ------------------ LINE -------------------

      private function onDown(e:MouseEvent):void
      {
         if (container.numChildren < 1) return;

         var offX:Number = CONTAINER_W - container.width;
         var offY:Number = CONTAINER_H - container.height;
         var rect:Rectangle = new Rectangle(offX, offY, Math.abs(offX), Math.abs(offY));

         container.startDrag(false, rect);
         stage.addEventListener(MouseEvent.MOUSE_UP, onStopDrag);
         stage.addEventListener(MouseEvent.ROLL_OUT, onStopDrag);
      }

      private function onStopDrag(e:MouseEvent):void
      {
         container.stopDrag();

         stage.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag);
         stage.removeEventListener(MouseEvent.ROLL_OUT, onStopDrag);
      }

      // ------------------ LINE -------------------

      // ------------------ LINE -------------------

   }

}